from typing import Union

from fastapi import APIRouter, Path, Depends, Body

from common.pkg.fastapi_util import cbv
from common.route.mall_route import MallMatchAPIRoute
from common.route.route import ZipCustomerRoute
from common.route.tenant_route import TenantBaseAPIRoute
from common.route.user_route import TenantMustLoginAPIRoute
from common.utils.depends.common import get_current_tenant
from common.utils.depends.tenant.mall import get_mall_info
from common.utils.depends.tips_depends import get_auth_code, get_login_tenant
from common.utils.lock.lock import add_red_lock_once
from common.utils.resp import JsonResponse, RC
from core.view import TenantBaseView
from schema.req_schema.mall_req_schema import UpdateMallModel, RegisterMallModel
from schema.resp_schema.mall_schema import MallResponseModel
from service.mall_service import MallService

router = APIRouter(prefix="/mall", tags=["mall"],  route_class=ZipCustomerRoute(TenantBaseAPIRoute, TenantMustLoginAPIRoute, MallMatchAPIRoute),
                   dependencies=[Depends(get_auth_code), Depends(get_login_tenant)])


@cbv(router)
class MallView(TenantBaseView):

    @router.post("/", description="注册新的mall")
    async def register_new_mall(self,
                                mall: RegisterMallModel = Body(...),
                                tenant_info: dict = Depends(get_current_tenant)
                                ):
        if not tenant_info:
            return JsonResponse(code=RC.TENANT_NOT_EXIST, msg="租户已删除").to_response()
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以创建mall").to_response()
        # 获取当前租户创建mall的锁 10s内不允许重复提交
        ok = await add_red_lock_once(self.redis, f"tenant:{self.tenant_id}:mall", self.request_id, 10)
        if not ok:
            return JsonResponse(code=RC.RATE_LIMIT, msg="请求太频繁,请稍后再试")
        ms = MallService(self.mgw, self.redis)
        ok, data_or_code = await ms.register_new_mall(self.tenant_id, mall)
        return self.unpack_response(ok, data_or_code)

    @router.get("/{code:str}", description="获取商城详情", response_model=MallResponseModel)
    async def get_mall_detail_info(self, mall_info: Union[None, dict] = Depends(get_mall_info)):
        if mall_info is None:
            return JsonResponse(code=RC.MALL_NOT_EXIST, msg="商城不存在")
        return MallResponseModel(data=mall_info)

    @router.put("/{code:str}", description="修改商城信息")
    async def update_mall_info(self,
                               code: str = Path(max_length=16),
                               mall: UpdateMallModel = Body(...),
                               tenant_info: Union[None, dict] = Depends(get_current_tenant),
                               mall_info: Union[None, dict] = Depends(get_mall_info)
                               ):
        if tenant_info is None:
            return JsonResponse(code=RC.MALL_NOT_EXIST, msg="商城已删除")
        if tenant_info.get("owner_id") != self.user_id:
            return JsonResponse(code=RC.FORBIDDING, msg="仅拥有者可以修改商城信息")
        data = mall.dict(exclude_unset=True)
        if not data:
            return JsonResponse(code=RC.PARAM_MISSING, msg="缺失参数").to_response()
        if mall_info is None:
            return JsonResponse(code=RC.MALL_NOT_EXIST, msg="商城不存在")
        ms = MallService(self.mgw, self.redis)
        ok, data_or_code = await ms.update_mall(code, old_version=mall_info.get("version"), **data)
        return self.unpack_response(ok, data_or_code)

